package cn.iutils.common.utils.office.html;

import cn.iutils.common.utils.BaseUtils;
import cn.iutils.common.utils.JFileUtils;
import org.docx4j.Docx4J;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.PageSizePaper;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.RFonts;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Entities;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.OutputStream;

/**
 * HTML转换工具
 * @author iutils.cn
 */
public class HtmlHelper extends BaseUtils {

    /**
     * 将页面保存为 docx
     *
     * @param url
     * @param path 文件地址
     * @param fileName 文件名
     * @return
     * @throws Exception
     */
    public File saveUrlToDocx(String url,String path,String fileName) throws Exception {
        return saveDocx(url2word(url),path,fileName);
    }

    /**
     * 将页面保存为 pdf
     *
     * @param url
     * @param path 文件地址
     * @param fileName 文件名
     * @return
     * @throws Exception
     */
    public File saveUrlToPdf(String url,String path,String fileName) throws Exception {
        return savePdf(url2word(url),path,fileName);
    }

    /**
     * 将页面转为 {@link org.docx4j.openpackaging.packages.WordprocessingMLPackage}
     *
     * @param url
     * @return
     * @throws Exception
     */
    public WordprocessingMLPackage url2word(String url) throws Exception {
        return xhtml2word(url2xhtml(url));
    }

    /**
     * 将 {@link org.docx4j.openpackaging.packages.WordprocessingMLPackage} 存为 docx
     *
     * @param wordMLPackage
     * @param path 文件地址
     * @param fileName 文件名
     * @return
     * @throws Exception
     */
    public File saveDocx(WordprocessingMLPackage wordMLPackage,String path,String fileName) throws Exception {
        JFileUtils.forceMkdir(new File(path));
        File file = new File(path, fileName + ".docx");
        wordMLPackage.save(file); //保存到 docx 文件
        return file;
    }

    /**
     * 将 {@link org.docx4j.openpackaging.packages.WordprocessingMLPackage} 存为 pdf
     *
     * @param wordMLPackage
     * @param path 文件地址
     * @param fileName 文件名
     * @return
     * @throws Exception
     */
    public File savePdf(WordprocessingMLPackage wordMLPackage,String path,String fileName) throws Exception {
        JFileUtils.forceMkdir(new File(path));
        File file = new File(path , fileName + ".pdf");
        OutputStream os = new java.io.FileOutputStream(file);
        Docx4J.toPDF(wordMLPackage, os);
        os.flush();
        os.close();
        return file;
    }

    /**
     * 将 {@link Document} 对象转为 {@link org.docx4j.openpackaging.packages.WordprocessingMLPackage}
     * xhtml to word
     * @param doc
     * @return
     * @throws Exception
     */
    protected WordprocessingMLPackage xhtml2word(Document doc) throws Exception {
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage(PageSizePaper.valueOf("A4"), true); //A4纸，//横版:true
        configSimSunFont(wordMLPackage); //配置中文字体
        XHTMLImporterImpl xhtmlImporter = new XHTMLImporterImpl(wordMLPackage);
        wordMLPackage.getMainDocumentPart().getContent().addAll( //导入 xhtml
                xhtmlImporter.convert(doc.html(), doc.baseUri()));
        return wordMLPackage;
    }

    /**
     * 将页面转为{@link Document}对象，xhtml 格式
     *
     * @param url
     * @return
     * @throws Exception
     */
    protected Document url2xhtml(String url) throws Exception {
        Document doc = Jsoup.connect(url).get(); //获得
        for (Element script : doc.getElementsByTag("script")) { //除去所有 script
            script.remove();
        }
        for (Element a : doc.getElementsByTag("a")) { //除去 a 的 onclick，href 属性
            a.removeAttr("onclick");
            a.removeAttr("href");
        }
        Elements links = doc.getElementsByTag("link"); //将link中的地址替换为绝对地址
        for (Element element : links) {
            String href = element.absUrl("href");
            element.attr("href", href);
        }
        doc.outputSettings()
                .syntax(Document.OutputSettings.Syntax.xml)
                .escapeMode(Entities.EscapeMode.xhtml);  //转为 xhtml 格式
        return doc;
    }

    /**
     * 为 {@link org.docx4j.openpackaging.packages.WordprocessingMLPackage} 配置中文字体
     *
     * @param wordMLPackage
     * @throws Exception
     */
    protected void configSimSunFont(WordprocessingMLPackage wordMLPackage) throws Exception {
        Mapper fontMapper = new IdentityPlusMapper();
        wordMLPackage.setFontMapper(fontMapper);
        RFonts rfonts = Context.getWmlObjectFactory().createRFonts(); //设置文件默认字体
        rfonts.setAsciiTheme(null);
        wordMLPackage.getMainDocumentPart().getPropertyResolver()
                .getDocumentDefaultRPr().setRFonts(rfonts);
    }
}
